#include "log.h"
#include "config.h"
#include <iostream>
#include <functional>

namespace johnsonli
{
	/*********** LogLevel ***********/
	const char* LogLevel::ToString(LogLevel::Level level)
	{
		switch (level) {
#define XX(name) \
		case LogLevel::name: \
			return #name; \
			break;

			XX(DEBUG);
			XX(INFO);
			XX(WARN);
			XX(ERROR);
			XX(FATAL);
#undef XX
		default:
			return "UNKNOW";
		}
		return "UNKNOW";
	}

	LogLevel::Level LogLevel::FromString(const std::string& str)
	{
#define XX(level, v) \
		if(str == #v) { \
			return LogLevel::level; \
		}
		XX(DEBUG, debug);
		XX(INFO, info);
		XX(WARN, warn);
		XX(ERROR, error);
		XX(FATAL, fatal);

		XX(DEBUG, DEBUG);
		XX(INFO, INFO);
		XX(WARN, WARN);
		XX(ERROR, ERROR);
		XX(FATAL, FATAL);
		return LogLevel::UNKNOW;
#undef XX
	}
	/*********** LogLevel ***********/

	/*********** LogEvent ***********/
	LogEvent::LogEvent(std::shared_ptr<Logger> logger, LogLevel::Level level
		, const char* file, int32_t line, uint32_t elapse
		, uint32_t thread_id, uint32_t fiber_id, uint64_t time
		, const std::string& thread_name)
		:m_file(file)
		, m_line(line)
		, m_elapse(elapse)
		, m_threadId(thread_id)
		, m_fiberId(fiber_id)
		, m_time(time)
		, m_threadName(thread_name)
		, m_logger(logger)
		, m_level(level) {
	}

	//LogEvent::~LogEvent()
	//{
	//	//死循环，ptr也是一个临时Event，这样就循环释放了
	//	m_logger->log(m_level, LogEvent::ptr(this));
	//}

	void LogEvent::format(const char* fmt, ...)
	{
		va_list al;
		va_start(al, fmt);
		format(fmt, al);
		va_end(al);
	}

	void LogEvent::format(const char* fmt, va_list al)
	{
		char* buf = nullptr;
		int len = vasprintf(&buf, fmt, al);
		if (len != -1) {
			m_ss << std::string(buf, len);
			free(buf);
		}
	}
	/*********** LogEvent ***********/

	/*********** LogEventWrap ***********/
	LogEventWrap::LogEventWrap(LogEvent::ptr event)
		:m_event(event)
	{}

	LogEventWrap::~LogEventWrap()
	{
		//在析构的时候完成日志输出
		if (m_event)
		{
			//std::cout << "~LogEventWrap" << std::endl;
			m_event->getLogger()->log(m_event->getLevel(), m_event);
		}
	}

	std::stringstream& LogEventWrap::getSS()
	{
		return m_event->getSS();
	}
	/*********** LogEventWrap ***********/

	class MessageFormatItem : public LogFormatter::FormatItem {
	public:
		MessageFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getContent();
			//std::cout << "m" << std::endl;
		}
	};

	class LevelFormatItem : public LogFormatter::FormatItem {
	public:
		LevelFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << LogLevel::ToString(level);
			//std::cout << "p" << std::endl;
		}
	};

	class ElapseFormatItem : public LogFormatter::FormatItem {
	public:
		ElapseFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getElapse();
			//std::cout << "r" << std::endl;
		}
	};

	class NameFormatItem : public LogFormatter::FormatItem {
	public:
		NameFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getLogger()->getName();
		}
	};

	class ThreadIdFormatItem : public LogFormatter::FormatItem {
	public:
		ThreadIdFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getThreadId();
		}
	};

	class FiberIdFormatItem : public LogFormatter::FormatItem {
	public:
		FiberIdFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getFiberId();
		}
	};

	class ThreadNameFormatItem : public LogFormatter::FormatItem {
	public:
		ThreadNameFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getThreadName();
		}
	};

	class DateTimeFormatItem : public LogFormatter::FormatItem {
	public:
		DateTimeFormatItem(const std::string& format = "%Y-%m-%d %H:%M:%S")
			:m_format(format) {
			if (m_format.empty()) {
				m_format = "%Y-%m-%d %H:%M:%S";
			}
		}

		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			struct tm tm;
			time_t time = event->getTime();
			localtime_r(&time, &tm);
			char buf[64];
			strftime(buf, sizeof(buf), m_format.c_str(), &tm);
			os << buf;
		}
	private:
		std::string m_format;
	};

	class FilenameFormatItem : public LogFormatter::FormatItem {
	public:
		FilenameFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getFile();
		}
	};

	class LineFormatItem : public LogFormatter::FormatItem {
	public:
		LineFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << event->getLine();
		}
	};

	class NewLineFormatItem : public LogFormatter::FormatItem {
	public:
		NewLineFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << std::endl;
		}
	};

	class StringFormatItem : public LogFormatter::FormatItem {
	public:
		StringFormatItem(const std::string& str)
			:m_string(str) {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << m_string;
		}
	private:
		std::string m_string;
	};

	class TabFormatItem : public LogFormatter::FormatItem {
	public:
		TabFormatItem(const std::string& str = "") {}
		void format(std::ostream& os, LogLevel::Level level, LogEvent::ptr event) override {
			os << "\t";
		}
	private:
		//std::string m_string;
	};

	/*********** LogFormatter ***********/
	LogFormatter::LogFormatter(const std::string& pattern)
		:m_pattern(pattern) {
		init();
	}

	std::string LogFormatter::format(LogLevel::Level level, LogEvent::ptr event) {
		//std::cout << "LogFormatter::format begin" << std::endl;
		std::stringstream ss;
		//std::cout << "m_items size: " << m_items.size() << std::endl;
		for (auto& i : m_items) {
			//std::cout << "m_items" << std::endl;
			i->format(ss, level, event);
			//std::cout << "m_items" << std::endl;
		}
		//std::cout << "1111111" << std::endl;
		//ss << event->getSS().str();
		//std::cout << "LogFormatter::format end" << std::endl;
		return ss.str();
	}

	std::ostream& LogFormatter::format(std::ostream& ofs, LogLevel::Level level, LogEvent::ptr event) {
		for (auto& i : m_items) {
			i->format(ofs, level, event);
		}
		return ofs;
	}

	//%xxx %xxx{xxx} %%
	//%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n
	void LogFormatter::init() {
		//str, format, type
		std::vector<std::tuple<std::string, std::string, int>> vec;
		std::string nstr;
		for (size_t i = 0; i < m_pattern.size(); ++i) {
			//普通字符
			if (m_pattern[i] != '%') {
				nstr.append(1, m_pattern[i]);
				continue;
			}

			//%%的形式，转义
			if ((i + 1) < m_pattern.size()) {
				if (m_pattern[i + 1] == '%') {
					nstr.append(1, '%');
					continue;
				}
			}

			size_t n = i + 1;
			int fmt_status = 0;
			size_t fmt_begin = 0;

			std::string str;
			std::string fmt;
			while (n < m_pattern.size()) {
				//正在处理str,不是字母，不是{}，str = [i+1，n]间的字符
				if (!fmt_status && (!isalpha(m_pattern[n]) && m_pattern[n] != '{'
					&& m_pattern[n] != '}')) {
					str = m_pattern.substr(i + 1, n - i - 1);
					break;
				}
				if (fmt_status == 0) {
					if (m_pattern[n] == '{') {
						str = m_pattern.substr(i + 1, n - i - 1);
						//std::cout << "*" << str << std::endl;
						fmt_status = 1; //解析格式
						fmt_begin = n;
						++n;
						continue;
					}
				}
				else if (fmt_status == 1) {
					if (m_pattern[n] == '}') {
						fmt = m_pattern.substr(fmt_begin + 1, n - fmt_begin - 1);
						//std::cout << "#" << fmt << std::endl;
						fmt_status = 0;
						++n;
						break;
					}
				}
				++n;
				if (n == m_pattern.size()) {
					if (str.empty()) {
						str = m_pattern.substr(i + 1);
					}
				}
			}

			if (fmt_status == 0) {
				if (!nstr.empty()) {
					vec.push_back(std::make_tuple(nstr, std::string(), 0));
					nstr.clear();
				}
				vec.push_back(std::make_tuple(str, fmt, 1));
				i = n - 1;
			}
			else if (fmt_status == 1) {
				std::cout << "pattern parse error: " << m_pattern << " - " << m_pattern.substr(i) << std::endl;
				m_error = true;
				vec.push_back(std::make_tuple("<<pattern_error>>", fmt, 0));
			}
		}

		if (!nstr.empty()) {
			vec.push_back(std::make_tuple(nstr, "", 0));
		}
		static std::map<std::string, std::function<FormatItem::ptr(const std::string& str)>> s_format_items = {
	#define XX(str, C) \
	        {#str, [](const std::string& fmt) { return FormatItem::ptr(new C(fmt));}}

			XX(m, MessageFormatItem),           //m:消息
			XX(p, LevelFormatItem),             //p:日志级别
			XX(r, ElapseFormatItem),            //r:累计毫秒数
			XX(c, NameFormatItem),              //c:日志名称
			XX(t, ThreadIdFormatItem),          //t:线程id
			XX(n, NewLineFormatItem),           //n:换行
			XX(d, DateTimeFormatItem),          //d:时间
			XX(f, FilenameFormatItem),          //f:文件名
			XX(l, LineFormatItem),              //l:行号
			XX(T, TabFormatItem),               //T:Tab
			XX(F, FiberIdFormatItem),           //F:协程id
			XX(N, ThreadNameFormatItem),        //N:线程名称
	#undef XX
		};

		for (auto& i : vec) {
			if (std::get<2>(i) == 0) {
				m_items.push_back(FormatItem::ptr(new StringFormatItem(std::get<0>(i))));
			}
			else {
				auto it = s_format_items.find(std::get<0>(i));
				if (it == s_format_items.end()) {
					m_items.push_back(FormatItem::ptr(new StringFormatItem("<<error_format %" + std::get<0>(i) + ">>")));
					m_error = true;
				}
				else {
					m_items.push_back(it->second(std::get<1>(i)));
				}
			}

			//std::cout << "(" << std::get<0>(i) << ") - (" << std::get<1>(i) << ") - (" << std::get<2>(i) << ")" << std::endl;
		}
		//std::cout << m_items.size() << std::endl;
	}
	/*********** LogFormatter ***********/

	/*********** Logger ***********/
	Logger::Logger(const std::string& name)
		:m_name(name),
		m_level(LogLevel::DEBUG)
	{
		//默认 DEBUG StdoutLogAppender
		m_appenders.push_back(LogAppender::ptr(new StdoutLogAppender));
	}

	Logger::Logger(LogLevel::Level level, const std::string& name)
		: m_name(name),
		m_level(level)
	{}

	/*Logger::ptr Logger::getInstance(LogLevel::Level level, const std::string& name)
	{
		static Logger::ptr logger(new Logger(level, name));
		logger->addAppender(LogAppender::ptr(new StdoutLogAppender));
		return logger;
	}*/

	void Logger::log(LogLevel::Level level, LogEvent::ptr event)
	{
		//std::cout << "log bebin" << std::endl;
		MutexType::Lock lock(m_mutex);
		// std::cout << "level : " << level  <<std::endl;

		// std::cout << "m_level : " << m_level  <<std::endl;
		if (level >= m_level)
		{
			for (auto& i : m_appenders)
			{
				i->log(level, event);
			}
		}
	}

	void Logger::debug(LogEvent::ptr event)
	{
		log(LogLevel::DEBUG, event);
	}

	void Logger::info(LogEvent::ptr event)
	{
		log(LogLevel::INFO, event);
	}

	void Logger::warn(LogEvent::ptr event)
	{
		log(LogLevel::WARN, event);
	}

	void Logger::error(LogEvent::ptr event)
	{
		log(LogLevel::ERROR, event);
	}

	void Logger::fatal(LogEvent::ptr event)
	{
		log(LogLevel::FATAL, event);
	}

	void Logger::addAppender(LogAppender::ptr appender)
	{
		MutexType::Lock lock(m_mutex);
		m_appenders.push_back(appender);
	}
	void Logger::delAppender(LogAppender::ptr appender)
	{
		MutexType::Lock lock(m_mutex);
		for (auto it = m_appenders.begin();
			it != m_appenders.end(); ++it)
		{
			if (*it == appender)
			{
				m_appenders.erase(it);
				break;
			}
		}
	}

	std::string Logger::toYamlString()
	{
		MutexType::Lock lock(m_mutex);
		YAML::Node node;
		//name;
		node["name"] = m_name;
		node["level"] = LogLevel::ToString(m_level);
		for (auto& a : m_appenders)
		{
			node["appenders"].push_back(YAML::Load(a->toYamlString()));
		}
		lock.unlock();

		std::stringstream ss;
		ss << node;
		return ss.str();
	}

	LogLevel::Level Logger::getLevel() 
	{ 
		return m_level; 
	}

	void Logger::setLevel(LogLevel::Level val) 
	{ 
		m_level = val; 
	}

	std::string Logger::getName() 
	{ 
		return m_name; 
	}

	void Logger::setName(std::string name) 
	{ 
		m_name = name; 
	}

	void Logger::clearAppenders() 
	{ 
		MutexType::Lock lock(m_mutex);
		m_appenders.clear(); 
	}

	/*********** Logger ***********/

	/*********** LogAppender ***********/
	LogAppender::LogAppender() {}
	LogAppender::~LogAppender() {}
	LogAppender::LogAppender(LogLevel::Level level, LogFormatter::ptr formater)
		:m_level(level),
		m_formater(formater)
	{

	}

	void LogAppender::setFormatter(LogFormatter::ptr val)
	{
		MutexType::Lock lock(m_mutex);
		m_formater = val; 
	}
	LogFormatter::ptr LogAppender::getFormatter() 
	{ 
		MutexType::Lock lock(m_mutex);
		return m_formater; 
	}

	LogLevel::Level LogAppender::getLevel() 
	{ 
		//MutexType::Lock lock(m_mutex);
		return m_level; 
	}

	void LogAppender::setLevel(LogLevel::Level val) 
	{ 
		//MutexType::Lock lock(m_mutex);
		m_level = val; 
	}

	/*********** LogAppender ***********/

	/*********** FileLogAppender ***********/
	FileLogAppender::FileLogAppender(const std::string& filename)
		:m_filename(filename),
		LogAppender(LogLevel::DEBUG, std::make_shared<LogFormatter>("%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n"))
	{
		reopen();
	}

	FileLogAppender::FileLogAppender(const std::string& filename, LogLevel::Level level, LogFormatter::ptr formater)
		: m_filename(filename),
		LogAppender(level, formater)
	{
		reopen();
	}

	FileLogAppender::~FileLogAppender()
	{
		if (m_filestream)
		{

			m_filestream.close();
		}
	}

	bool FileLogAppender::reopen()
	{
		MutexType::Lock lock(m_mutex);
		if (m_filestream)
		{
			m_filestream.close();
		}
		m_filestream.open(m_filename, std::ios::app);
		//
		return !!m_filestream;
	}

	void FileLogAppender::log(LogLevel::Level level, LogEvent::ptr event)
	{	
		//std::cout << "FileLogAppender bebin" << std::endl;
		if (level >= m_level)
		{
			uint64_t now = event->getTime();
			if (now >= (m_lastTime + 3)) {
				reopen();
				m_lastTime = now;
			}

			MutexType::Lock lock(m_mutex);
			m_filestream << m_formater->format(level, event);
			m_filestream.flush();
			//m_filestream.close();
			//std::cout << m_formater->format(level, event) << "11111111" << std::endl;
		}
	}

	std::string FileLogAppender::toYamlString()
	{
		YAML::Node node;
		node["type"] ="FileLogAppender";
		MutexType::Lock lock(m_mutex);
		node["file"] = m_filename;
		node["level"] = LogLevel::ToString(m_level);
		node["formatter"] = m_formater->getPattern();

		std::stringstream ss;
		ss << node;
		return ss.str();
	}
	/*********** FileLogAppender ***********/

	/*********** StdoutLogAppender ***********/
	StdoutLogAppender::StdoutLogAppender()
		//%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n
		:LogAppender(LogLevel::DEBUG, std::make_shared<LogFormatter>("%d{%Y-%m-%d %H:%M:%S}%T%t%T%N%T%F%T[%p]%T[%c]%T%f:%l%T%m%n"))
	{}

	StdoutLogAppender::StdoutLogAppender(LogLevel::Level level, LogFormatter::ptr formater)
		:LogAppender(level, formater)
	{}

	void StdoutLogAppender::log(LogLevel::Level level, LogEvent::ptr event)
	{
		MutexType::Lock lock(m_mutex);
		//std::cout << "StdoutLogAppender bebin" << std::endl;
		//std::cout << "level: " << LogLevel::ToString(level) << " m_level: " << LogLevel::ToString(m_level) << std::endl;
		if (level >= m_level)
		{
			//std::cout << "cout bebin" << std::endl;
			std::cout << m_formater->format(level, event) << std::endl;
			//std::cout << "cout end" << std::endl;
		}
	}

	std::string StdoutLogAppender::toYamlString()
	{

		YAML::Node node;
		node["type"] = "StdoutLogAppender";
		MutexType::Lock lock(m_mutex);
		node["level"] = LogLevel::ToString(m_level);
		node["formatter"] = m_formater->getPattern();

		std::stringstream ss;
		ss << node;
		return ss.str();
	}
	/*********** StdoutLogAppender ***********/

	LoggerManager::LoggerManager()
	{
		//默认 DEBUG StdoutLogAppender
		m_root.reset(new Logger("root"));
		m_loggers[m_root->getName()] = m_root;
		//std::cout << "LoggerManager" << std::endl;
	}

	Logger::ptr LoggerManager::getLogger(const std::string& name)
	{
		MutexType::Lock lock(m_mutex);
		auto it = m_loggers.find(name);
		if (it != m_loggers.end())
		{
			return it->second;
		}
		
		//默认 DEBUG StdoutLogAppender
		Logger::ptr logger(new Logger(name));
		m_loggers[name] = logger;
		return logger;
	}

	std::string LoggerManager::toYamlString()
	{
		MutexType::Lock lock(m_mutex);
		YAML::Node node;
		for (auto& l : m_loggers)
		{
			node.push_back(YAML::Load(l.second->toYamlString()));
		}

		std::stringstream ss;
		ss << node;
		return ss.str();
	}


	//LogAppender
	struct LogAppenderDefine
	{
		int type = 0; //1 File, 2 Stdout
		LogLevel::Level level = LogLevel::UNKNOW;
		std::string formatter;
		std::string file;

		bool operator==(const LogAppenderDefine& oth) const
		{
			return type == oth.type
				&& level == oth.level
				&& formatter == oth.formatter
				&& file == oth.file;
		}
	};

	//Logger
	struct LogDefine
	{
		std::string name;
		LogLevel::Level level = LogLevel::UNKNOW;
		std::vector<LogAppenderDefine> appenders;
		
		bool operator==(const LogDefine& oth) const
		{
			return name == oth.name
				&& level == oth.level
				&& appenders == oth.appenders;
		}

		bool operator<(const LogDefine& oth) const
		{
			return name < oth.name;
		}
	};

	//LogDefine偏特化 YAML string to LogDefine
	template<>
	class LexicalCast<std::string, LogDefine>
	{
	public:
		LogDefine operator()(const std::string& str)
		{
			//yaml string格式的LogDefine 转成Yaml Node
			YAML::Node n = YAML::Load(str);
			LogDefine ld;
			//name
			if (!n["name"].IsDefined()) {
				std::cout << "log config error: name is null, " << n
					<< std::endl;
				throw std::logic_error("log config name is null");
			}
			ld.name = n["name"].as<std::string>();
			//level
			ld.level = LogLevel::FromString(n["level"].IsDefined() ? n["level"].as<std::string>() : "");
			//appenders
			if (n["appenders"].IsDefined())
			{
				//n["appenders"] == vector<LogAppenderDefine>
				for (size_t x = 0; x < n["appenders"].size(); ++x)
				{
					auto a = n["appenders"][x];
					if (!a["type"].IsDefined()) {
						std::cout << "log config error: appender type is null, " << a
							<< std::endl;
						continue;
					}
					std::string type = a["type"].as<std::string>();
					LogAppenderDefine lad;
					if (type == "FileLogAppender")
					{
						//appender type
						lad.type = 1;
						//appender file
						if (!a["file"].IsDefined()) {
							std::cout << "log config error: fileappender file is null, " << a
								<< std::endl;
							continue;
						}
						lad.file = a["file"].as<std::string>();
						
					}
					else if(type == "StdoutLogAppender")
					{
						lad.type = 2;
					}
					else
					{
						std::cout << "log config error: appender type is invalid, " << a
							<< std::endl;
						continue;
					}
					//appender level
					if (a["level"].IsDefined())
					{
						lad.level = LogLevel::FromString(a["level"].IsDefined() ? a["level"].as<std::string>() : "");
					}

					//appender formatter
					if (a["formatter"].IsDefined()) {
						lad.formatter = a["formatter"].as<std::string>();
					}
					ld.appenders.push_back(lad);
				}
			}
			return ld;
		}
	};

	//LogDefine偏特化 LogDefine to YAML string 
	template<>
	class LexicalCast<LogDefine, std::string> {
	public:
		std::string operator()(const LogDefine& i) {
			YAML::Node n;
			n["name"] = i.name;
			if (i.level != LogLevel::UNKNOW) {
				n["level"] = LogLevel::ToString(i.level);
			}

			for (auto& a : i.appenders) {
				YAML::Node na;
				if (a.type == 1) {
					na["type"] = "FileLogAppender";
					na["file"] = a.file;
				}
				else if (a.type == 2) {
					na["type"] = "StdoutLogAppender";
				}
				if (a.level != LogLevel::UNKNOW) {
					na["level"] = LogLevel::ToString(a.level);
				}

				if (!a.formatter.empty()) {
					na["formatter"] = a.formatter;
				}

				n["appenders"].push_back(na);
			}
			std::stringstream ss;
			ss << n;
			return ss.str();
		}
	};

	johnsonli::ConfigVar<std::set<LogDefine>>::ptr g_log_defines =
		johnsonli::Config::Lookup("logs", std::set<LogDefine>(), "logs config");

	//LoadFromYaml（YAML string to T） --> 在SetValue中观察者模式触发日志更改事件 --> 调用回调函数(添加、修改、删除) 
	struct  LogIniter
	{
		LogIniter()
		{
			g_log_defines->addListener([] (const std::set<LogDefine>& old_val, const std::set<LogDefine>& new_val) {
				//std::cout << "addListener" << std::endl;
//				LOG_INFO(LOG_ROOT()) << "on_logger_conf_changed";
				for (auto& i : new_val)
				{
					auto it = old_val.find(i);//用LogDefine的operator<比较
					//添加，new_val有，old_val没有
					johnsonli::Logger::ptr logger;
					if (it != old_val.end())
					{
						//新增logger，没找到就会自动添加一个
						logger = LOG_NAME(i.name);
					}
					else
					{
						//修改，new_val, old_val都有，但是不相等
						if (!(i == *it))
						{
							logger = LOG_NAME(i.name);
						}
						else //没改变的
						{
							continue;
						}
					}

					//给logger进行设置
					logger->setLevel(i.level);
					logger->clearAppenders();
					for (auto& a : i.appenders)
					{
						johnsonli::LogAppender::ptr ap;
						if (a.type == 1) //File
						{
							ap.reset(new FileLogAppender(a.file));
						}
						else if (a.type == 2) //Stdout
						{
							//std::cout << "ap.reset(new StdoutLogAppender());" << std::endl;
							ap.reset(new StdoutLogAppender());
						}

						ap->setLevel(a.level);
						if (!a.formatter.empty())
						{
							LogFormatter::ptr fmt(new LogFormatter(a.formatter));
							if (!fmt->isError()) {
								ap->setFormatter(fmt);
							}
							else {
								std::cout << "log.name=" << i.name << " appender type=" << a.type
									<< " formatter=" << a.formatter << " is invalid" << std::endl;
							}
						}
						logger->addAppender(ap);
					}

				}

				//删除
				for (auto& i : old_val)
				{
					auto it = new_val.find(i);//用LogDefine的operator<比较
					if(it == new_val.end())
					{
						//删除logger
						auto logger = LOG_NAME(i.name);
						logger->setLevel((LogLevel::Level)0);
						logger->clearAppenders();
					}
				}

				//std::cout << "change end" << std::endl;
			});
		}
	};

	static LogIniter __log_init;
}
